/*
	mips32r2.h
	
	Definition of MIPS32r2 related identifiers
*/

#ifndef ISAMIPS_QEMU_MIPS32R2
#define ISAMIPS_QEMU_MIPS32R2

#include "universal.h"

#define TriggerSWI0 \
	asm volatile ( \
		"mfc0 $t0, $13, 0\n\t" \
		"li $t1, 0x00000100\n\t" \
		"or $t0, $t0, $t1\n\t" \
		"mtc0 $t0, $13, 0\n\t" \
		: /*no inputs*/ \
		: /*no outputs*/ \
		: "t0", "t1", "t2" \
	)

#define TriggerSWI1 \
	asm volatile ( \
		"mfc0 $t0, $13, 0\n\t" \
		"li $t1, 0x00000200\n\t" \
		"or $t0, $t0, $t1\n\t" \
		"mtc0 $t0, $13, 0\n\t" \
		: /*no inputs*/ \
		: /*no outputs*/ \
		: "t0", "t1", "t2" \
	)

#define ReadCP0Value(val, reg, sel) \
	asm volatile ( \
		"mfc0 %0, $%1, %2\n\t" \
		: "=r"(val) \
		: "i"(reg), "i"(sel) \
		: /*no clobbers*/ \
	)
	
#define WriteCP0Value(val, reg, sel) \
	asm volatile ( \
		"mtc0 %0, $%1, %2\n\t" \
		: /*no output*/ \
		: "r"(val), "i"(reg), "i"(sel) \
		: /*no clobbers*/ \
	)


#define SSNOP asm volatile ( \
	"ssnop\n\t" \
		: /*no outputs*/ \
		: /*no inputs*/ \
		: /*no clobbers*/ \
	)

#define NOP asm volatile ( \
		"nop\n\t" \
		: /*no outputs*/ \
		: /*no inputs*/ \
		: /*no clobbers*/ \
	)

#define EHB asm volatile ( \
		"ehb\n\t" \
		: /*no outputs*/ \
		: /*no inputs*/ \
		: /*no clobbers*/ \
	)

#define SYSCALLPTR(syscdptr, syscretdptr) \
	asm volatile ( \
		"addiu $a2, %0, 0 \n\t" \
		"addiu $a3, %1, 0 \n\t" \
		"syscall \n\t" \
		: /*no output params*/ \
		: "r"(syscdptr), "r"(syscretdptr) \
		: "a2", "a3" \
	)

void mips32r2Init(void);

void mips32r2EnableInterrupt(void);

uint32 mips32r2InterruptService(reg32b, uint32*, SyscallDescriptor*, SyscallReturnDescriptor*);

void setSW0ISRCallback(void callback (*)(void));

void setSW1ISRCallback(void callback (*)(void));

void setTLBLoadStoreISRCallback(void callback (*)(reg8b, reg32b, reg32b));

void seti8259aISRCallback(void (*)(void));

void setMemorySyscallISRCallback(void callback (*)(reg32b, uint32*, SyscallDescriptor*, SyscallReturnDescriptor*));

void setProcSyscallISRCallback(void callback (*)(reg32b, uint32*, SyscallDescriptor*, SyscallReturnDescriptor*));

uint32 mips32r2GetProcessorID(void);

#endif

